package com.leo;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.*;
import javafx.scene.image.WritableImage;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.KeyCode;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.*;
import javafx.scene.paint.Paint;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Callback;

/**
 * @ClassName TreeViewEventDemo
 * @Description 拖拽
 * @Author wangss
 * @date 2020.06.14 23:22
 * @Version 1.0
 */
public class TreeViewDragDemo extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        AnchorPane an = new AnchorPane();
        an.setStyle("-fx-background-color: #f4fffe");

        TreeView<String> treeView = new TreeView<>();
        treeView.setPrefHeight(400d);

        TreeItem<String> root = new TreeItem<>("中国");

        TreeItem<String> hlj = new TreeItem<>("黑龙江省");
        TreeItem<String> cityhlj = new TreeItem<>("黑龙江");
        TreeItem<String> cityheb = new TreeItem<>("哈尔滨");
        TreeItem<String> citydq = new TreeItem<>("大庆");

        TreeItem<String> hn = new TreeItem<>("河南省");
        TreeItem<String> citypy = new TreeItem<>("濮阳");
        TreeItem<String> cityzz = new TreeItem<>("郑州");
        TreeItem<String> citykf = new TreeItem<>("开封");

        TreeItem<String> js = new TreeItem<>("江苏省");
        TreeItem<String> citynj = new TreeItem<>("南京");
        TreeItem<String> cityjs = new TreeItem<>("江苏");

        treeView.setRoot(root);
        root.getChildren().addAll(hlj, hn, js);
        hlj.getChildren().addAll(cityhlj, cityheb, citydq);
        hn.getChildren().addAll(citypy, cityzz, citykf);
        js.getChildren().addAll(citynj, cityjs);

        // 自动展开
        root.setExpanded(true);
        hlj.setExpanded(true);
        hn.setExpanded(true);
        js.setExpanded(true);

        AnchorPane.setTopAnchor(treeView, 50d);
        AnchorPane.setLeftAnchor(treeView, 100d);
        an.getChildren().addAll(treeView);

        Scene scene = new Scene(an);
        primaryStage.setScene(scene);
        primaryStage.setTitle("TreeView");
        primaryStage.setWidth(800d);
        primaryStage.setHeight(800d);
        primaryStage.show();

        treeView.setEditable(true);
        treeView.setCellFactory(new Callback<TreeView<String>, TreeCell<String>>() {

            TreeCell<String> temp = null;
            TreeItem<String> oldTreeItem = null;

            @Override
            public TreeCell<String> call(TreeView<String> param) {

                TreeCell<String> treeCell = new TreeCell<String>() {

                    @Override
                    public void startEdit() {
                        super.startEdit();
                        HBox hBox = new HBox();

                        TextField tf = new TextField(this.getItem());
                        hBox.getChildren().add(tf);

                        this.setGraphic(hBox);

                        tf.requestFocus();

                        tf.setOnKeyPressed(event -> {
                            if (event.getCode() == KeyCode.ENTER) {
                                this.commitEdit(tf.getText());
                            }
                        });
                    }

                    @Override
                    public void cancelEdit() {
                        super.cancelEdit();

                        HBox hBox = new HBox();

                        Label label = new Label(this.getItem());

                        hBox.getChildren().add(label);

                        this.setGraphic(hBox);
                    }

                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);

                        if (!empty) {
                            HBox hBox = new HBox();

                            Label label = new Label(item);

                            hBox.getChildren().add(label);

                            // 可以设置图标
                            if (this.getTreeItem().isExpanded()) {
                                this.setDisclosureNode(new Text("-"));
                            } else {
                                this.setDisclosureNode(new Text("+"));
                            }

                            this.setGraphic(hBox);
                        } else {
                            this.setGraphic(null);
                        }
                    }
                };

                treeCell.setOnDragEntered(event -> {
//                    treeCell.getTreeView().getFocusModel().focus(treeCell.getIndex());
//                    System.out.println(treeCell.getHeight());
                });

                treeCell.setOnDragDetected(event -> {
                    Dragboard dragboard = treeCell.startDragAndDrop(TransferMode.COPY_OR_MOVE);

                    ClipboardContent clipboardContent = new ClipboardContent();
                    clipboardContent.putString(treeCell.getItem());
                    oldTreeItem = treeCell.getTreeItem();

                    Text text = new Text(treeCell.getItem());
                    text.setFont(new Font(15));

                    WritableImage wi = new WritableImage((int) treeCell.getWidth() - 200, 20);
                    text.snapshot(new SnapshotParameters(), wi);

                    dragboard.setDragView(wi, (treeCell.getWidth() - 200) / 2, 10);
                    dragboard.setContent(clipboardContent);
                });

                treeCell.setOnDragOver(event -> {
                    event.acceptTransferModes(TransferMode.COPY);

                    // treeCell是没进入一个cell都会改变
                    if (temp != null) {
                        temp.setBorder(null);
                    }
                    temp = treeCell;

                    if (event.getY() > treeCell.getHeight() - 10 && event.getY() <= treeCell.getHeight()) {
                        BorderStroke borderStroke = new BorderStroke(null, null, Paint.valueOf("#FFF555"), null,
                                null, null, BorderStrokeStyle.SOLID, null, new CornerRadii(5), new BorderWidths(2), new Insets(1));
                        Border border = new Border(borderStroke);
                        treeCell.setBorder(border);
                    }
                });

                treeCell.setOnDragDropped(event -> {

                    // 父节点不能移动
                    if (!oldTreeItem.isLeaf()) {
                        treeCell.setBorder(null);
                        return;
                    }

                    String value = event.getDragboard().getString();

                    if (!treeCell.getTreeItem().isLeaf()) {
                        treeCell.getTreeItem().getChildren().add(0, new TreeItem<>(value));
                        // 移除原来的
                        oldTreeItem.getParent().getChildren().remove(oldTreeItem);
                        treeCell.setBorder(null);
                        return;
                    }

                    // 如果当前cell有父节点
                    if (treeCell.getTreeItem().getParent() != null) {
                        int index = treeCell.getTreeItem().getParent().getChildren().indexOf(treeCell.getTreeItem());

//                        System.out.println(treeCell.getItem() + " : " + treeCell.getIndex() + " : " + index);

                        treeCell.getTreeItem().getParent().getChildren().add(index + 1, new TreeItem<>(value));

                        // 移除原来的
                        oldTreeItem.getParent().getChildren().remove(oldTreeItem);
                        treeCell.setBorder(null);
                    }
                });

                return treeCell;
            }
        });
    }
}
